<template>
    <div class="jsplumb-container">
        <div class="jsplumb-flow-menu">
            <div class="flow-menu-item" :class="[data.collectionList.length ? 'noDrag' : '']" :draggable="!data.collectionList.length" @dragstart="drag({type: 1})">
                <i class="el-icon-full-screen"></i>
                <div>AFS集群</div>
            </div>
            <div class="flow-menu-item" draggable="true" @dragstart="drag({type: 2})">
                <i class="el-icon-office-building"></i>
                <div>AFS机柜</div>
            </div>
            <div class="flow-menu-item" draggable="true" @dragstart="drag({type: 3})">
                <i class="el-icon-mobile"></i>
                <div>AFS</div>
            </div>
            <div class="flow-menu-item" @click="isConnect=true">
                <i class="el-icon-bottom-right"></i>
                <div>连线</div>
            </div>
            <div class="flow-menu-item" @click="isConnect=false">
                <i class="el-icon-rank"></i>
                <div>选择</div>
            </div>
        </div>
        <div class="jsplumb-flow-detail">
            <el-button type="primary" size="mini" style="position: absolute; right: 50px; top: 25px; z-index: 1;" @click="save">保存</el-button>
            <div id="flowContent"
                class="flowMain"
                ref="flowContent"
                @drop="drop($event)"
                @dragover="allowDrop($event)">
                <flowNode
                    ref="flowNode"
                    :list="data.collectionList"
                    :isconnect="isConnect"
                    @delete-node="deleteNode"
                    @change-node-site="changeNodeSite"
                    @changeNode="changeNode"
                    @edit-node="editNode"></flowNode>
            </div>
        </div>
        <div class="jsplumb-flow-edit">
            <div class="flow-edit-content">
                <edit-collection ref="editCollection" v-show="editType == 1" @changeNode="changeNode"></edit-collection>
                <edit-group ref="editGroup" v-show="editType == 2" @changeNode="changeNode"></edit-group>
                <edit-device ref="editDevice" :selectedDeviceList="selectedDeviceList" v-show="editType == 3" @changeNode="changeNode"></edit-device>
            </div>
        </div>
        <el-dialog :visible.sync="editLineDialogVisible" width="60%" style="height: 100%;" append-to-body>
            <component ref="editLine" :is="editType == 4 ? 'editLine' : ''" @changeLine="changeLine"></component>
        </el-dialog>
    </div>
</template>
<script>
import {jsPlumb} from 'jsplumb';
import flowNode from './components/flowNode.vue';
import editCollection from './components/edit-collection.vue';
import editGroup from './components/edit-group.vue';
import editDevice from './components/edit-device.vue';
import editLine from './components/edit-line.vue';
import {uniqWith, filter, concat} from "lodash";
export default {
    props: {
        jsplumbParams: {
            type: Object,
            default () {
                return {}
            }
        }
    },
    components: {flowNode, editCollection, editGroup, editDevice, editLine},
    data () {
        return {
            selectedDeviceList: new Set(),
            jsPlumb: null, // jsPlumb实例
            currentItem: null, // 当前拖拽的元素
            data: {
                collectionList: [], // 存集合
                lineList: [], // 存连线关系
            },
            editType: 0, // 编辑的类型 1-afs集群 2-afs机柜 3-afs设备 4-连线
            isConnect: false, // 判断是否连接
            // 默认设置参数
            jsplumbSetting: {
                // 动态锚点、位置自适应
                Anchors: ['Top', 'TopCenter', 'TopRight', 'TopLeft', 'Right', 'RightMiddle', 'Bottom', 'BottomCenter',
                    'BottomRight', 'BottomLeft', 'Left', 'LeftMiddle'
                ],
                Container: 'flowContent',
                // 连线的样式 StateMachine、Flowchart,有四种默认类型：Bezier（贝塞尔曲线），Straight（直线），Flowchart（流程图），State machine（状态机）
                Connector: 'Bezier',
                //这个是鼠标拉出来的线的属性
                ConnectionOverlays: [
                    ["Label", {
                        label: "afs-afs",
                        id: "label-1",
                        cssClass: "csslabel",
                        fill: '#A3D1FF'
                    }]
                ],
                // 鼠标不能拖动删除线
                ConnectionsDetachable: false,
                // 删除线的时候节点不删除
                DeleteEndpointsOnDetach: false,
                // 连线的端点
                Endpoint: ["Dot", {radius: 5}],
                Endpoint: ["Rectangle", {
                    height: 10,
                    width: 10
                }],
                // 线端点的样式
                EndpointStyle: {
                    fill: 'rgba(255,255,255,0)',
                    outlineWidth: 1
                },
                LogEnabled: true, //是否打开jsPlumb的内部日志记录
                // 绘制线
                PaintStyle: {
                    stroke: '#409eff',
                    strokeWidth: 4,
                },
                // 绘制箭头
                Overlays: [
                    // ['Arrow', {
                    //     width: 8,
                    //     length: 8,
                    //     location: 1
                    // }],
                ],
                RenderMode: "svg"
            },
            // jsplumb连接参数
            jsplumbConnectOptions: {
                isSource: true,
                isTarget: true,
                // 动态锚点、提供了4个方向 Continuous、AutoDefault
                anchor: "Continuous",
            },
            jsplumbSourceOptions: {
                filter: ".flow-node-drag",  //触发连线的区域
                /*"span"表示标签，".className"表示类，"#id"表示元素id*/
                filterExclude: false,
                anchor: "Continuous",
                allowLoopback: true, // 回环，自连
            },
            jsplumbTargetOptions: {
                filter: ".flow-node-drag",
                /*"span"表示标签，".className"表示类，"#id"表示元素id*/
                filterExclude: false,
                anchor: "Continuous",
                allowLoopback: true, // 回环，自连
            },
            // 是否加载完毕
            loadEasyFlowFinish: false,
            currentConnect: '', // 当前的连接线
            currentLine: '', // 当前连接线数据
            editLineDialogVisible: false,
            timer: null,
            currentNode: {
                from: '',
                to: '',
                from_deviceId: '',
                to_deviceId: '',
                label: '',
                uuid: '',
                Remark: '',
                connRelates: [],
            }
        }
    },
    methods: {
        init () {
            this.jsPlumb.ready(() => {
                console.log(this.jsPlumb, '---')
                // 导入默认配置
                this.jsPlumb.importDefaults(this.jsplumbSetting);
                // 会使整个jsPlumb立即重绘
                this.jsPlumb.setSuspendDrawing(false, true);
                // 单点连接线（编辑label）,
                this.jsPlumb.bind('click', (conn, originalEvent) => {
                    clearTimeout(this.timer);
                    this.timer = setTimeout(() => { // 这里采用执行自定义事件的方式
                        console.log("click", conn);
                        this.editLine(conn);
                    }, 300); // 延迟300ms执行单击事件,区分双击事件
                    // conn.getOverlay("label-1").setLabel('惊呆了老铁'); // 初始化label
                })
                // 双击连接线（删除）
                this.jsPlumb.bind('dblclick', (conn, originalEvent) => {
                    console.log(conn, '----')
                    clearTimeout(this.timer);
                    this.$confirm('确定删除此连接关系吗？', '提示', {
                        type: 'warning'
                    }).then(() => {
                        this.jsPlumb.deleteConnection(conn);
                    }).catch(() => {})
                })
                // 连线前检查
                this.jsPlumb.bind("beforeDrop", (evt) => {
                    let from = evt.sourceId;
                    let to = evt.targetId;
                    if (this.hasLine(from, to)) {
                        this.$message.error('只能有一条连接关系');
                        return false
                    }
                    if (this.hashOppositeLine(from, to)) {
                        this.$message.error('只能有一条连接关系');
                        return false
                    }
                    return true
                })
                // 连线
                this.jsPlumb.bind("connection", (evt) => {
                    console.log('connecting-连接中...', evt)
                    let from = evt.source.id
                    let to = evt.target.id
                    let from_deviceId =  evt.source.title.split(',')[0]
                    let to_deviceId = evt.target.title.split(',')[0]
                    let from_deviceName = evt.source.title.split(',')[1]
                    let to_deviceName = evt.target.title.split(',')[1]
                    console.log(from_deviceName, to_deviceName)
                    console.log('--this.loadEasyFlowFinish--', this.loadEasyFlowFinish)
                    if (this.loadEasyFlowFinish) {
                        this.data.lineList.push({
                            from: from,
                            to: to,
                            from_deviceId: from_deviceId,
                            to_deviceId: to_deviceId,
                            label: `${from_deviceName} - ${to_deviceName}`,
                            uuid: this.getUUID(),
                            Remark: '',
                        })
                        evt.connection.getOverlay("label-1").setLabel(`${from_deviceName} - ${to_deviceName}`); //初始化label
                    };
                    // this.editLine(evt.connection);
                })
                // 删除连线
                this.jsPlumb.bind("connectionDetached", (evt) => {
                    // console.log('connectionDetached', evt)
                    this.deleteLine(evt.sourceId, evt.targetId);
                })
                // this.loadFlow(this.data);
            })
        },
        hasLine (from, to) {
            for (let i = 0; i < this.data.lineList.length; i++) {
                let line = this.data.lineList[i];
                if (line.from === from && line.to === to) {
                    return true;
                }
            }
            return false;
        },
        hashOppositeLine(from, to) {
            return this.hasLine(to, from)
        },
        drag (item) {
            this.currentItem = item;
        },
        drop (event) {
            event.preventDefault();
            var _obj = this.$refs.flowContent;
            var temp = {
                uuid: this.getUUID(),
                top: event.offsetY + 'px',
                left: event.offsetX + 'px',
                type: this.currentItem.type,
                mouseEnter: false
            }
            this.addNode(temp, event);
            this.editNode(temp);
        },
        allowDrop (event) {
            event.preventDefault(); // 阻止默认行为
        },
        // 增加节点
        addNode (temp, event) {
            console.log(temp, event)
            if (temp.type == 1) {
                // 集群
                if (event.target.getAttribute('myTag') !== 'collection') {
                    this.$message.error('必须先放置集群');
                    return;
                }
                this.data.collectionList.push(temp);
            } else if (temp.type == 2) {
                // 机柜
                if (event.target.getAttribute('myTag') !== 'group') {
                    this.$message.error('机柜必须放到集群内');
                    return;
                }
                this.data.collectionList.forEach(item => {
                    if (item.uuid == event.target.parentNode.id) {
                        if (item.children && item.children.length) {
                            let arr = item.children;
                            item.children = [...arr, {...temp, parentId: item.uuid}];
                        } else {
                            item.children = [{...temp, parentId: item.uuid}];
                        }
                    }
                })
            } else if  (temp.type == 3) {
                // 设备
                if (event.target.getAttribute('myTag') !== 'device') {
                    this.$message.error('设备必须放到机柜内');
                    return;
                }
                this.data.collectionList.forEach(item1 => {
                    item1.children.forEach(item2 => {
                        if (item2.uuid == event.target.parentNode.id) {
                            if (item2.children && item2.children.length) {
                                let arr = item2.children;
                                item2.children = [...arr, {...temp, parentId: item2.uuid}];
                            } else {
                                item2.children = [{...temp, parentId: item2.uuid}];
                            }
                        }
                    })
                })
            }
            this.$nextTick(function() {
                let timer = setInterval(() => {
                    if (document.getElementById(temp.uuid)) {
                        if (temp.type == 3) {
                            this.jsPlumb.makeSource(temp.uuid, this.jsplumbSourceOptions)
                            this.jsPlumb.makeTarget(temp.uuid, this.jsplumbTargetOptions)
                        }
                        this.jsPlumb.draggable(temp.uuid, {
                            containment: 'parent'
                        })
                        clearInterval(timer);
                    }
                }, 100)
                this.initSelectedDeviceList()
            })
        },
        //删除节点
        deleteNode (node) {
            this.$confirm('确定删除当前节点吗？', '提示', {
                type: 'warning',
                closeOnClickModal: false
            }).then(() => {
                console.log(node)
                let flag = true
                if (node.type == 1) {
                    if (node.children && node.children.length) {
                        this.$message.error('先删除机柜再删除集群');
                        flag = false
                        return;
                    }
                } else if (node.type == 2) {
                    if (node.children && node.children.length) {
                        this.$message.error('先删除设备再删除机柜');
                        flag = false
                        return;
                    }
                } else if (node.type == 3) {
                    this.data.lineList.forEach(ele => {
                        if (ele.from == node.uuid || ele.to == node.uuid) {
                            this.$message.error('先删除连接关系再删除设备');
                            flag = false
                            return;
                        }
                    })
                }
                if (!flag) {
                    return
                }
                this.loopFun(this.data.collectionList, node.uuid, (item, index, list) => {
                    list.splice(index, 1)
                })
                this.$nextTick(function() {
                    this.jsPlumb.removeAllEndpoints(node.uuid);
                })
                node.deviceId && this.selectedDeviceList.has(node.deviceId) && this.selectedDeviceList.delete(node.deviceId)
            }).catch(() => {})
            return true
        },
        //编辑节点
        editNode(temp) {
            if (temp.type == 1) {
                this.editType = 1;
                this.$nextTick(function() {
                    this.$refs['editCollection'].init(this.data.collectionList, temp)
                })
            } else if (temp.type == 2) {
                this.editType = 2;
                this.$nextTick(function() {
                    this.$refs['editGroup'].init(this.data.collectionList, temp)
                })
            } else if (temp.type == 3) {
                this.editType = 3;
                this.$nextTick(function() {
                    this.$refs['editDevice'].init(this.data.collectionList, temp)
                })
            }
            this.currentNode = temp
            this.$nextTick(() => {
                this.initSelectedDeviceList()
            })
        },
        // 编辑线
        editLine (conn) {
            console.log('编辑线', this.data.lineList, conn.sourceId, conn.targetId)
            this.currentConnect = conn;
            this.data.lineList.forEach((item, index) => {
                if (item.from == conn.sourceId && item.to == conn.targetId) {
                    this.currentLine = item;
                    setTimeout(() => {
                        this.editType = 4;
                        this.editLineDialogVisible = true;
                        this.$nextTick(function() {
                            this.$refs['editLine'].init(this.data.lineList, item)
                        })
                    }, 100)
                }
            })
        },
        // 删除连线
        deleteLine (from, to) {
            this.data.lineList.forEach((ele, index) => {
                if (ele.from == from && ele.to == to) {
                    this.data.lineList.splice(index, 1);
                }
            })
        },
        // 改变节点的位置
        changeNodeSite(data) {
            // for (var i = 0; i < this.data.nodeList.length; i++) {
            //     let node = this.data.nodeList[i]
            //     if (node.id === data.nodeId) {
            //         node.left = data.left
            //         node.top = data.top
            //     }
            // }
        },
        changeNode (item) {
            this.loopFun(this.data.collectionList, item.uuid, (ele, index, list) => {
                for (const key in item.params) {
                    if (Object.hasOwnProperty.call(item.params, key)) {
                        this.$set(ele, key, item.params[key]); // 给ele循环添加属性值
                    }
                }
            })
            this.data.collectionList = JSON.parse(JSON.stringify(this.data.collectionList)) // 强制更新数据

            if (this.selectedDeviceList.has(item.params.deviceId)) {
                return
            }
            if (item.params.deviceId) {
                this.data.lineList = this.data.lineList.map(e => {
                    const oldEdge = this.jsPlumb.getConnections({
                        source: e.from,
                        target: e.to,
                    })
                    let obj = null
                    if (this.currentNode.deviceId === e.from_deviceId) {
                        obj = Object.assign(e, {
                            from: item.uuid,
                            to: e.to,
                            from_deviceId: item.params.deviceId,
                            to_deviceId: e.to_deviceId,
                            label: `${item.params.deviceName} - ${e.label.split(',')[1]}`,
                            uuid: this.getUUID(),
                            Remark: '',
                            connRelates: [],
                        })
                    }
                    if (this.currentNode.deviceId === e.to_deviceId) {
                        obj = Object.assign(e, {
                            from: e.from,
                            to: item.uuid,
                            from_deviceId: e.from_deviceId,
                            to_deviceId: item.params.deviceId,
                            label: `${e.label.split(',')[0]} - ${item.params.deviceName}`,
                            uuid: this.getUUID(),
                            Remark: '',
                            connRelates: [],
                        })
                    }
                    if (obj) {
                        if (oldEdge) {
                            oldEdge.forEach(v => {
                                this.jsPlumb.deleteConnection(v);
                            })
                            //
                        }
                        let connection = this.jsPlumb.connect({
                            source: e.from,
                            target: e.to,
                        }, this.jsplumbConnectOptions);
                        connection.getOverlay("label-1").setLabel(e.label)
                    }
                    return obj ? obj : e
                })
                this.jsPlumb.setSuspendDrawing(false, true);
            }
            this.selectedDeviceList.has(this.currentNode.deviceId)
            && this.selectedDeviceList.delete(this.currentNode.deviceId)
            && this.selectedDeviceList.add(item.params.deviceId)
        },
        changeLine (item) {
            this.loopFun(this.data.lineList, item.uuid, (ele, index, list) => {
                for (const key in item.params) {
                    if (Object.hasOwnProperty.call(item.params, key)) {
                        this.$set(ele, key, item.params[key]); // 给ele循环添加属性值
                    }
                }
            })
            this.data.lineList = JSON.parse(JSON.stringify(this.data.lineList)) // 强制更新数据
            this.editLineDialogVisible = false;
        },
        save () {
            console.log('生成的结构', this.data)
            let flag = true
            // 校验集群信息是否完善
            if (!this.data.collectionList[0].clusterId) {
                this.$message.error('请完善集群信息');
                flag = false
                return;
            }
            let obj = {};
            obj.id = this.data.collectionList[0].id || null,
            obj.clusterId = this.data.collectionList[0].clusterId;
            obj.clusterName = this.data.collectionList[0].clusterName;
            obj.regionId = this.data.collectionList[0].roomId || this.data.collectionList[0].stationId; // 有机房传机房，没机房传站点
            obj.stationId = this.data.collectionList[0].stationId;
            obj.roomId = this.data.collectionList[0].roomId;
            obj.ip = this.data.collectionList[0].ip;
            obj.port = this.data.collectionList[0].port;
            obj.cabinetNum = this.data.collectionList[0].children.length;
            obj.clusterCabinets = [];
            this.data.collectionList[0].children.forEach(ele1 => {
                if (!ele1.cabinetId) {
                    this.$message.error(`请完善机柜${ele1.uuid}信息`);
                    flag = false
                    return;
                }
                let cabinetDevices = [];
                if (ele1.children) {
                    ele1.children.forEach(ele2 => {
                        if (!ele2.deviceId) {
                            this.$message.error(`请完善设备${ele2.uuid}信息`);
                            flag = false
                            return;
                        }
                        cabinetDevices.push({
                            id: ele2.id || null,
                            deviceId: ele2.deviceId
                        })
                    })
                }
                obj.clusterCabinets.push({
                    id: ele1.id || null,
                    cabinetUuid: ele1.uuid,
                    cabinetId: ele1.cabinetId,
                    cabinetName: ele1.cabinetName,
                    clusterId: this.data.collectionList[0].clusterId,
                    cabinetDevices: cabinetDevices,
                })
            })
            obj.connRelates = [];
            this.data.lineList.forEach(ele1 => {
                if (!ele1.connRelates || !ele1.connRelates.length) {
                    this.$message.error(`请完善${ele1.from_deviceId}和${ele1.to_deviceId}之间的连接关系`);
                    flag = false
                    return;
                }
                if (ele1.connRelates && ele1.connRelates) {
                    ele1.connRelates.forEach(ele2 => {
                        obj.connRelates.push({
                            id: ele2.id || null,
                            startDeviceId: ele2.startDeviceId,
                            startDeviceFaceId: ele2.startDeviceFaceId,
                            startPortId: ele2.startPortId,
                            endDeviceId: ele2.endDeviceId,
                            endDeviceFaceId: ele2.endDeviceFaceId,
                            endPortId: ele2.endPortId
                        });
                    })
                }
            })
            if (!flag) {
                return
            }
            obj.clusterCabinets.forEach((v) => {
                if (v.cabinetDevices.length <= 1) {
                    flag = false
                }
            })
            for(let i =0;i<obj.clusterCabinets.length; i++) {
                if (obj.clusterCabinets[i].cabinetDevices.length <= 1) {
                    this.$message.error(`${obj.clusterCabinets[i].cabinetName}内至少有一台设备`);
                    flag = false
                    return
                }
            }
            if (!flag) {
                return
            }
            if (obj.connRelates.length <= 0) {
                this.$message.error('集群内至少存在一条连接关系');
                return
            }
            console.log('生成的结构', obj)
        },
        packageData (obj) {
            // 回显组装数据
            this.data.collectionList = [];
            this.data.lineList = [];
            // 回显集群
            this.data.collectionList.push({
                id: obj.id,
                top: '250px',
                left: '248px',
                uuid: this.getUUID(),
                clusterName: obj.clusterName,
                clusterId: obj.clusterId,
                type: 1,
                mouseEnter: false,
                regionId: obj.regionIds[obj.regionIds.length - 1],
                regionName: obj.regionNames[obj.regionNames.length - 2],
                stationId: obj.stationId,
                stationName: obj.stationName,
                roomId: obj.roomId,
                roomName: obj.roomName,
                ip: obj.ip,
                port: obj.port,
                children: []
            })
            // 回显机柜和设备
            if (obj.clusterCabinets && obj.clusterCabinets.length) {
                obj.clusterCabinets.forEach(ele1 => {
                    let arr = [];
                    if (ele1.cabinetDevices && ele1.cabinetDevices.length) {
                        ele1.cabinetDevices.forEach((ele2, index2) => {
                            arr.push({
                                id: ele2.id,
                                uuid: this.getUUID(),
                                top: `${100 * (Math.random() * ele1.cabinetDevices.length).toFixed(2)}px`,
                                left: `${100 * (Math.random() * ele1.cabinetDevices.length).toFixed(2)}px`,
                                type: 3,
                                mouseEnter: false,
                                parentId: ele1.uuid,
                                deviceId: ele2.deviceId,
                                deviceName: ele2.deviceName
                            })
                        })
                    }
                    this.data.collectionList[0].children.push({
                        id: ele1.id,
                        uuid: this.getUUID(),
                        top: `${250 * (Math.random() * obj.clusterCabinets.length).toFixed(2)}px`,
                        left: `${248 * (Math.random() * obj.clusterCabinets.length).toFixed(2)}px`,
                        type: 2,
                        parentId: this.data.collectionList[0].uuid,
                        cabinetId: ele1.cabinetId,
                        cabinetName: ele1.cabinetName,
                        mouseEnter: false,
                        children: arr || [],
                    })
                })
            }
            // 回显连接关系
            if (obj.connRelates && obj.connRelates.length) {
                // 根据后端返回的连接关系connRelates，对数组进行分组
                let result1 = uniqWith(obj.connRelates, (item1, item2) => {
                    if (
                        (item1.startDeviceId == item1.endDeviceId)
                        ||
                        (item2.startDeviceId == item2.endDeviceId)
                    ) {
                        return true;
                    }
                })
                // result1是取出startDeviceId和endDeviceId不相等的连接关系
                // console.log('list1', result1)
                let result2 = uniqWith(result1, (item1, item2) => {
                    if (
                        (item1.startDeviceId == item2.endDeviceId && item1.endDeviceId == item2.startDeviceId)
                        ||
                        (item1.startDeviceId == item2.startDeviceId && item1.endDeviceId == item2.endDeviceId)
                    ) {
                        return true;
                    }
                })
                // result2是取出result1里startDeviceId和endDeviceId不相等且不重复的连接关系
                // console.log('result2', result2) // 取出不同，且不重复
                let result3 = filter(obj.connRelates, (item1) => {
                    if (
                        (item1.startDeviceId == item1.endDeviceId)
                    ) {
                        return true;
                    }
                })
                // result3是取出startDeviceId和endDeviceId相等的连接关系
                // console.log('result3', result3)
                let result4  = uniqWith(result3, (item1, item2) => {
                    if (
                        (item1.startDeviceId == item2.endDeviceId && item1.endDeviceId == item2.startDeviceId)
                        ||
                        (item1.startDeviceId == item2.startDeviceId && item1.endDeviceId == item2.endDeviceId)
                    ) {
                        return true;
                    }
                })
                // result4是取出result3里startDeviceId和endDeviceId相等但不重复的连接关系
                // console.log('result4', result4) // 取出相同,且不重复
                let relateList = concat(result2, result4);
                // console.log('relateList', relateList)
                if (relateList && relateList.length) {
                    relateList.forEach(ele1 => {
                        if (ele1.startDeviceId == ele1.endDeviceId) {
                            // 如果是自连
                            let arr = [];
                            obj.connRelates.forEach(ele2 => {
                                if (
                                    (ele1.startDeviceId === ele2.startDeviceId && ele1.endDeviceId === ele2.endDeviceId)
                                    ||
                                    (ele1.startDeviceId === ele2.endDeviceId && ele1.endDeviceId === ele2.startDeviceId)
                                ) {
                                    arr.push({
                                        id: ele2.id,
                                        startDeviceId: ele2.startDeviceId,
                                        startDeviceFaceId: ele2.startFaceId,
                                        startPortId: ele2.startPortId,
                                        endDeviceId: ele2.endDeviceId,
                                        endPortId: ele2.endPortId,
                                        endDeviceFaceId: ele2.endFaceId,
                                    })
                                }
                            })
                            let from = '';
                            let to = '';
                            this.loopFun2(this.data.collectionList, ele1.startDeviceId, 'deviceId', (e, index, list) => {
                                from = e.uuid;
                            })
                            this.loopFun2(this.data.collectionList, ele1.endDeviceId, 'deviceId', (e, index, list) => {
                                to = e.uuid;
                            })
                            this.data.lineList.push({
                                from: from,
                                to: to,
                                from_deviceId: ele1.startDeviceId,
                                to_deviceId: ele1.endDeviceId,
                                label: `${ele1.startDeviceName} - ${ele1.endDeviceName}`,
                                uuid: this.getUUID(),
                                Remark: '',
                                connRelates: arr,
                            })
                        } else {
                            let arr = [];
                            obj.connRelates.forEach(ele2 => {
                                if (
                                    (ele1.startDeviceId === ele2.startDeviceId || ele1.startDeviceId === ele2.endDeviceId)
                                    &&
                                    (ele1.endDeviceId === ele2.startDeviceId || ele1.endDeviceId === ele2.endDeviceId)
                                ) {
                                    arr.push({
                                        id: ele2.id,
                                        startDeviceId: ele2.startDeviceId,
                                        startDeviceFaceId: ele2.startFaceId,
                                        startPortId: ele2.startPortId,
                                        endDeviceId: ele2.endDeviceId,
                                        endPortId: ele2.endPortId,
                                        endDeviceFaceId: ele2.endFaceId,
                                    })
                                }
                            })
                            let from = '';
                            let to = '';
                            this.loopFun2(this.data.collectionList, ele1.startDeviceId, 'deviceId', (e, index, list) => {
                                from = e.uuid;
                            })
                            this.loopFun2(this.data.collectionList, ele1.endDeviceId, 'deviceId', (e, index, list) => {
                                to = e.uuid;
                            })
                            this.data.lineList.push({
                                from: from,
                                to: to,
                                from_deviceId: ele1.startDeviceId,
                                to_deviceId: ele1.endDeviceId,
                                label: `${ele1.startDeviceName} - ${ele1.endDeviceName}`,
                                uuid: this.getUUID(),
                                Remark: '',
                                connRelates: arr,
                            })
                        }
                    })
                }
            }
            console.log('this.data', JSON.parse(JSON.stringify(this.data)))
            console.log(this.data)
            this.initSelectedDeviceList()
            this.$nextTick(() => {
                this.loadFlow(this.data);
            })
        },
        initSelectedDeviceList(){
            this.selectedDeviceList.clear()
            this.data.collectionList.forEach(v => {
                v.children && v.children.forEach( k=> {
                    k.children && k.children.forEach(e => {
                        e.deviceId && this.selectedDeviceList.add(e.deviceId)
                    })
                })
            })
        },
        loadFlow (data) {
            // 设置节点可拖拽
            let loopFun = list => {
                list.forEach((e, i) => {
                    if (e.type == 3) {
                        this.jsPlumb.makeSource(e.uuid, this.jsplumbSourceOptions);
                        this.jsPlumb.makeTarget(e.uuid, this.jsplumbTargetOptions);
                    }
                    this.jsPlumb.draggable(e.uuid, {
                        containment: 'parent'
                    })
                    if (e.children && e.children.length) {
                        loopFun(e.children);
                    }
                })
            }
            loopFun(data.collectionList);
            // 初始化连线
            data.lineList.forEach(e => {
                let connection = this.jsPlumb.connect({
                    source: e.from,
                    target: e.to,
                }, this.jsplumbConnectOptions);
                console.log('e.label', e.label)
                connection.getOverlay("label-1").setLabel(e.label); //初始化label
            })
            this.$nextTick(function() {
                this.loadEasyFlowFinish = true;
            })
        },
        loopFun(list, uuid, callback) {
            list.forEach((e, i) => {
                if (e.uuid == uuid) {
                    callback(e, i, list);
                } else {
                    if (e.children) {
                        this.loopFun(e.children, uuid, callback);
                    }
                }
            })
        },
        loopFun2 (list, id, key, callback) {
            list.forEach((e, i) => {
                if (e[key] == id) {
                    callback(e, i, list);
                } else {
                    if (e.children) {
                        return this.loopFun2(e.children, id, key, callback);
                    }
                }
            })
        },
        // 随机生成一个uuid值
        getUUID() {
            var s = [];
            var hexDigits = "0123456789abcdef";
            for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
            }
            s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
            s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
            s[8] = s[13] = s[18] = s[23] = "-";
            var uuid = s.join("");
            return uuid;
        },
    },
    mounted () {
        this.jsPlumb = jsPlumb.getInstance();
        this.$nextTick(() => {
            this.init();
        });
        console.log('jsplumbParams', this.jsplumbParams)
        if (JSON.stringify(this.jsplumbParams) !== '{}') {
            this.packageData(this.jsplumbParams);
        } else {
            this.loadEasyFlowFinish = true
        }
    }
}
</script>
<style>
.jtk-connector {
    cursor: pointer;
    user-select: none;
}
.jtk-connector:hover {
    box-shadow: 0 0 6px #409eff;
}
.csslabel {
    color: #fff!important;
}
</style>
<style lang="scss" scoped>
.jsplumb-container {
    display: flex;
    height: calc(100vh - 70px);
    color: #606266;
    .jsplumb-flow-menu {
        width: 100px;
        // padding: 10px;
        height: auto;
        margin: 0 10px;
        border: 1px solid #EBEEF5;
        padding: 12px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
        word-break: break-all;
        // border-radius: 4px;
        background: #fff;
        .flow-menu-item {
            text-align: center;
            box-shadow: 0 0 4px #A3D1FF;
            margin-bottom: 8px;
            cursor: pointer;
            font-size: 14px;
            color: #A3D1FF;
            padding: 5px 0;
            border-radius: 5px;
            user-select: none;
            > i {
                font-size: 40px;
            }
        }
        .noDrag {
            color: #696969;
            cursor: not-allowed;
        }
    }
    .jsplumb-flow-detail {
        flex: 1;
        border: 1px solid #EBEEF5;
        padding: 12px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
        word-break: break-all;
        border-radius: 4px;
        position: relative;
        background: #fff;
        height: auto;
        .flowMain {
            width: 100%;
            height: 100%;
            position: relative;
        }
    }
    .jsplumb-flow-edit {
        height: auto;
        width: 400px;
        padding: 10px 10px;
        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
        margin: 0 10px;
        background: #fff;
        border-radius: 4px;
    }
}
</style>
